home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #2 / Ham Radio 2000 - Volume 2.iso / HAMV2 / TCP_IP / TNOS230S / BID_WP.C < prev    next >
C/C++ Source or Header  |  1997-09-07  |  23KB  |  1,017 lines

  1. #include "global.h"
  2. #include "commands.h"
  3. #include "files.h"
  4. #ifndef MSDOS
  5. #include "ctype.h"
  6. #include <sys/stat.h>
  7. #endif
  8. #include "timer.h"
  9. #include "proc.h"
  10. #include "bm.h"
  11. #include "pool.h"
  12.  
  13.  
  14. #if !defined(_lint)
  15. static char rcsid[] OPTIONAL = "$Id: bid_wp.c,v 1.25 1997/09/07 21:18:28 root Exp root $";
  16. #endif
  17.  
  18. extern char *wpageCheck (char *string, int bbs, int updateit, char which);
  19. extern void sortit (const char *fname, int entrysize, int searchsize, int strsize, time_t age);
  20. static void Oldbidtick (void *p);
  21. static void Oldbidprocess (int a, void *v1, void *v2);
  22. static int dotimer (int argc, char *argv[], void *p);
  23. static int doexpkick (int argc, char *argv[], void *p);
  24. static int dobidkick (int argc, char *argv[], void *p);
  25. static int doage (int argc, char *argv[], void *p);
  26. int dombbid (int argc, char *argv[], void *p);
  27.  
  28. #ifdef WPAGES
  29. static void exp_function (const char *funcname, const char *filename, const char *fname, int theage, struct timer * thetimer, int strsize, int sortsize);
  30. static int dotempage (int argc, char *argv[], void *p);
  31. static void TempWPages (void);
  32. extern void wpageAdd (char *entry, int bbs, int updateit, char which);
  33. static int dowpsupport (int argc, char *argv[], void *p);
  34. int wpserver (FILE * fp, const char *from);
  35. static int dowpserver (int argc, char *argv[], void *p);
  36. static int dowpclient (int argc, char *argv[], void *p);
  37. static int dowpupdate (int argc, char *argv[], void *p);
  38. static int dowpdest (int argc, char *argv[], void *p);
  39. static int dowpclicall (int argc, char *argv[], void *p);
  40. static void WPUpdatetick (void *p);
  41. static void Oldwpagestick (void *p);
  42. static void Oldwpagesprocess (int a, void *v1, void *v2);
  43. void add_WPUpdate (char *call, char *home, char *name, char which);
  44. #endif
  45.  
  46. #ifdef POOLED
  47. static int dobidmemory (int argc, char **argv, void *p);
  48. static int dobidcount (int argc, char *argv[], void *p);
  49. static void bid_load (int mode);
  50. #endif
  51.  
  52. extern int expired;
  53. void bid_delete (register char *string);
  54. int bid_check (register char *string);
  55. void bid_add (char *bid, time_t now, int tofile, char *to);
  56.  
  57. static char OpenErr[] = "expire: err %d opening %s";
  58. static char RenErr[] = "expire: err %d renaming %s to %s";
  59. static char WriteErr[] = "expire: err %d writing %s";
  60.  
  61. #define MSPMINUTE (1000L*60L)
  62.  
  63. extern char *BIDsuffix;
  64.  
  65.  
  66. #ifdef WPAGES
  67. #define WPDEST    10
  68. #define MSPHOUR (1000L*60L*60L)
  69. #define MSPDAY  (1000L*60L*60L*24)
  70.  
  71. static char *WPdestinations[WPDEST];
  72. static char *WPcall;
  73. static struct timer WPUpdatetimer;
  74. static int WPClient, WPServer;
  75. int MbWpages = 1;
  76. static int WPtempAge = 30;
  77. #endif
  78.  
  79.  
  80. extern char *Mbhaddress;
  81. extern char *mbxRCall;
  82.  
  83.  
  84. #ifdef POOLED
  85. static int MemBid = 0;
  86.  
  87. struct membid {
  88.     struct membid *next;
  89.     char bid[14];
  90.     long time;
  91.     char to[14];
  92. };
  93.  
  94. #define NULLMEMBID ((struct membid *)0)
  95.  
  96. static struct membid *MemBidTop;
  97.  
  98. static struct mempool membid_pool = { NULLPOOLBLK, NULLPOOLBLK, 0, sizeof (struct membid), 50 };
  99.  
  100.  
  101.  
  102. static int
  103. dobidmemory (int argc, char *argv[], void *p OPTIONAL)
  104. {
  105. int was, retval;
  106.  
  107.     was = MemBid;
  108.     retval = setbool (&MemBid, "Access bid history from memory", argc, argv);
  109.     if (was != MemBid)
  110.         pool_free (&membid_pool);
  111.     if (MemBid)
  112.         bid_load (1);
  113.     return (retval);
  114. }
  115.  
  116.  
  117.  
  118. static int
  119. dobidcount (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
  120. {
  121. struct mempoolblock *mpb = (struct mempoolblock *) 0;
  122. long count = 0;
  123. int blocks = 0;
  124.  
  125.     if (!MemBid)
  126.         tputs ("Bids are not being stored in memory\n");
  127.     else {
  128.         for (mpb = membid_pool.top; mpb; mpb = mpb->next) {
  129.             if (!mpb->next)
  130.                 count += (long) membid_pool.index;
  131.             else
  132.                 count += membid_pool.numentries;
  133.             blocks++;
  134.         }
  135.         tprintf ("There are %ld Bids in memory in %d memory blocks\n", count, blocks);
  136.     }
  137.     return (0);
  138. }
  139. #endif
  140.  
  141.  
  142.  
  143. #ifdef WPAGES
  144. static struct cmds OLDcmds[] =
  145. {
  146.     { "age",        doage,        0, 0, NULLCHAR },
  147.     { "client",        dowpclient,    0, 0, NULLCHAR },
  148.     { "clientcall",        dowpclicall,    0, 0, NULLCHAR },
  149.     { "destinations",    dowpdest,    0, 0, NULLCHAR },
  150.     { "kick",        doexpkick,   2048, 0, NULLCHAR },
  151.     { "timer",        dotimer,    0, 0, NULLCHAR },
  152.     { "server",        dowpserver,    0, 0, NULLCHAR },
  153.     { "support",        dowpsupport,    0, 0, NULLCHAR },
  154.     { "temporaryage",    dotempage,    0, 0, NULLCHAR },
  155.     { "update",        dowpupdate,    0, 0, NULLCHAR },
  156.     { NULLCHAR,        NULL,        0, 0, NULLCHAR }
  157. };
  158. #endif
  159.  
  160.  
  161.  
  162. static struct cmds OLDbidcmds[] =
  163. {
  164.     { "age",    doage,        0, 0, NULLCHAR },
  165. #ifdef POOLED
  166.     { "count",    dobidcount,    0, 0, NULLCHAR },
  167. #endif
  168.     { "kick",    dobidkick,   2048, 0, NULLCHAR },
  169. #ifdef POOLED
  170.     { "memory",    dobidmemory,    0, 0, NULLCHAR },
  171. #endif
  172.     { "timer",    dotimer,    0, 0, NULLCHAR },
  173.     { NULLCHAR,    NULL,        0, 0, NULLCHAR }
  174. };
  175.  
  176.  
  177.  
  178. int
  179. dooldbids (int argc, char **argv, void *p OPTIONAL)
  180. {
  181.     return (subcmd (OLDbidcmds, argc, argv, (void *) 1));
  182. }
  183.  
  184.  
  185.  
  186. #ifdef WPAGES
  187. int
  188. dooldwpages (int argc, char *argv[], void *p OPTIONAL)
  189. {
  190.     return (subcmd (OLDcmds, argc, argv, (void *) 0));
  191. }
  192.  
  193.  
  194.  
  195. static void
  196. exp_function (funcname, filename, fname, theage, thetimer, strsize, sortsize)
  197. const char *funcname, *fname OPTIONAL;
  198. const char *filename;
  199. int theage;
  200. struct timer *thetimer;
  201. int strsize, sortsize;
  202. {
  203. time_t age;
  204. int didit;
  205.  
  206.     stop_timer (thetimer);
  207.     log (-1, "%s: processing", funcname);
  208.     kwait (NULL);
  209.  
  210.     didit = merge (filename);    /* add in contents of '.new' file */
  211.     if (!didit)
  212.         return;        /* skip expire if no NEW extries - for performance */
  213.     age = (time_t) (theage * 86400L);
  214.     sortit (filename, strsize + 17, sortsize, strsize, age);    /* sort entire file */
  215.  
  216.     if (expired)
  217.         log (-1, "%s: %d expired", funcname, expired);
  218.     start_detached_timer (thetimer);
  219.     return;
  220. }
  221. #endif /* WPAGES */
  222.  
  223.  
  224.  
  225. /******************************************************************/
  226. /* This program will deleted old BID's from the history file,
  227.  * after making a backup copy.
  228.  *
  229.  *  Eg. 'oldbids 24 30' will try to delete all bids older then 30 days
  230.  *      every 24 hours.
  231.  *      'oldbids now' will do it now, with set value of age.
  232.  *
  233.  * Copyright 1992, Johan. K. Reinalda, WG7J/PA3DIS
  234.  *      email : johan@ece.orst.edu
  235.  *      packet: wg7j@wg7j.or.usa.na
  236.  *
  237.  * Any part of this source may be freely distributed for none-commercial,
  238.  * amateur radio use only, as long as credit is given to the author.
  239.  *
  240.  * v1.0 920325
  241.  * Modified to add oldwpages using shared code TNOS 1.0     BAL
  242.  */
  243. static struct timer Oldbidtimer;
  244. static int Oldbid_age = 30;
  245.  
  246. #ifdef WPAGES
  247. static struct timer Oldwpagestimer;
  248. static int Oldwpages_age = 30;
  249. #endif
  250.  
  251.  
  252.  
  253. static void
  254. Oldbidprocess (int a OPTIONAL, void *v1 OPTIONAL, void *v2 OPTIONAL)
  255. {
  256. int i, hasexpired = 0;
  257. char *cp, *cp2;
  258. FILE *old, *new;
  259. time_t now;
  260. time_t age;
  261. time_t bidtime;
  262. #define LEN 80
  263. char *newfile;
  264. char buf[LEN];
  265.  
  266.  
  267.     stop_timer (&Oldbidtimer);
  268.     log (-1, "Oldbid: processing");
  269.     age = (time_t) (Oldbid_age * 86400L);
  270.     kwait (NULL);
  271.  
  272.  
  273.     newfile = (char *) mallocw (strlen (Historyfile) + 5);
  274.     sprintf (newfile, "%s.new", Historyfile);
  275.     unlink (newfile);
  276.     if ((old = fopen (Historyfile, READ_TEXT)) == NULLFILE) {
  277.         log (-1, OpenErr, errno, Historyfile);
  278.         return;
  279.     }
  280.     if ((new = fopen (newfile, WRITE_TEXT)) == NULLFILE) {
  281.         (void) fclose (old);
  282.         log (-1, OpenErr, errno, newfile);
  283.         free (newfile);
  284.         return;
  285.     }
  286.     now = time (&now);
  287.  
  288.     while (fgets (buf, LEN, old) != NULL) {
  289.         kwait (NULL);
  290.         rip (buf);
  291.         if (*buf == '$')
  292.             continue;    /* skip deleted bid */
  293.         if ((cp = strchr (buf, ' ')) != NULLCHAR) {
  294.             /*found one with timestamp*/
  295.             *cp++ = '\0';    /* now points to timestamp */
  296.             cp2 = skipwhite (cp);
  297.             cp2 = skipnonwhite (cp2);
  298.             cp2 = skipwhite (cp2);
  299.             if ((bidtime = atol (cp)) == 0L)
  300.                 /*something wrong, re-stamp */
  301.                 fprintf (new, "%-13.13s %-14ld %s\n", buf, now, cp2);
  302.             else {
  303.                 /* Has this one expired yet ? */
  304.                 if (now - bidtime < age)
  305.                     fprintf (new, "%-13.13s %-14ld %s\n", buf, bidtime, cp2);
  306.                 else
  307.                     hasexpired++;
  308.             }
  309.         } else {
  310.             /* This is an old one without time stamp,
  311.              * add to the new file with current time as timestamp
  312.              */
  313.             fprintf (new, "%-13.13s %-14ld unknown\n", buf, now);
  314.         }
  315.         kwait (NULL);
  316.     }
  317.  
  318.     i = ferror (new);
  319.     (void) fclose (old);
  320.     (void) fclose (new);
  321.  
  322.     if (!i) {
  323.         unlink (Historyfile);
  324.         if (rename (newfile, Historyfile) == -1)
  325.             log (-1, RenErr, errno, newfile, Historyfile);
  326.     } else
  327.         log (-1, WriteErr, errno, newfile);
  328.  
  329.     free (newfile);
  330.     if (hasexpired)
  331.         log (-1, "Oldbid: %d expired", hasexpired);
  332.     start_detached_timer (&Oldbidtimer);
  333.     return;
  334. }
  335.  
  336.  
  337.  
  338. static void
  339. Oldbidtick (void *p OPTIONAL)
  340. {
  341.     if (newproc ("Oldbid", 2048, Oldbidprocess, 0, NULL, NULL, 0) == NULLPROC)
  342.         log (-1, "Couldn't start Oldbid process");
  343. }
  344.  
  345.  
  346.  
  347. #ifdef WPAGES
  348. static int
  349. dotempage (int argc, char *argv[], void *p OPTIONAL)
  350. {
  351.     if (argc < 2)
  352.         tprintf ("WP Temporary Assignment age: %d days\n", WPtempAge);
  353.     else
  354.         WPtempAge = atoi (argv[1]);
  355.     return 0;
  356. }
  357.  
  358.  
  359.  
  360. static void
  361. TempWPages ()
  362. {
  363. FILE *fp;
  364. long offset, validentries = 0;
  365. char buf[LINELEN], *cp;
  366. time_t then, now;
  367.  
  368.  
  369.     (void) time (&now);
  370.     if ((fp = fopentmp (WhitePages, READ_TEXT)) != NULLFILE) {
  371.         while (offset = ftell (fp), fgets (buf, LINELEN - 1, fp)) {
  372.             kwait (NULL);
  373.             if (*buf == '$')
  374.                 continue;
  375.             cp = skipnonwhite (buf);
  376.             *cp++ = 0;
  377.             cp = skipwhite (cp);
  378.             then = atol (cp);
  379.             if ((then + (WPtempAge * MSPDAY)) > now) {
  380.                 validentries++;
  381. #if 0
  382.                 tcmdprintf ("temp: entry '%s' to remain %ld days\n", buf,
  383.                         ((then + (WPtempAge * MSPDAY)) - now) / MSPDAY);
  384. #endif
  385.                 continue;
  386.             }
  387.             wpageAdd (buf, 0, 1, 'T');
  388.             mark_forwarded (fp, offset, '$');
  389.         }
  390.         (void) fclose (fp);
  391.         if (!validentries) {
  392.             sprintf (buf, "%s.tmp", WhitePages);
  393.             unlink (buf);
  394.         }
  395.     }
  396.     kwait (NULL);
  397. }
  398.  
  399.  
  400.  
  401. void
  402. RenewWPages ()
  403. {
  404.     exp_function ("Oldwpages", WhitePages, "wpages", Oldwpages_age, &Oldwpagestimer, 13, 6);
  405. }
  406.  
  407.  
  408.  
  409. static void
  410. Oldwpagesprocess (int a OPTIONAL, void *v1 OPTIONAL, void *v2 OPTIONAL)
  411. {
  412.     setMaintenance ();
  413.     exp_function ("Oldwpages", WhitePagesBBS, "wpagebbs", Oldwpages_age, &Oldwpagestimer, 32, 6);
  414.     RenewWPages ();
  415.     TempWPages ();
  416.     clearMaintenance ();
  417. }
  418.  
  419.  
  420.  
  421. static void
  422. Oldwpagestick (void *p OPTIONAL)
  423. {
  424.     if (newproc ("Oldwpages", 2048, Oldwpagesprocess, 0, NULL, NULL, 0) == NULLPROC)
  425.         log (-1, "Couldn't start Oldwpages process");
  426. }
  427.  
  428. #endif /* WPAGES */
  429.  
  430.  
  431. static const char *names[] = { "White Pages", "Bulletin ID" };
  432.  
  433.  
  434.  
  435. static int
  436. dotimer (int argc, char *argv[], void *p)
  437. {
  438. struct timer *thetimer;
  439. void (*thefunc) (void *);    /* Function to call at expiration */
  440.  
  441. #ifdef WPAGES
  442.     thetimer = (p) ? &Oldbidtimer : &Oldwpagestimer;
  443.     thefunc = (p) ? Oldbidtick : Oldwpagestick;
  444. #else
  445.     thetimer = &Oldbidtimer;
  446.     thefunc = Oldbidtick;
  447. #endif
  448.     if (argc < 2) {
  449.         tprintf ("%s timer: %lu/%lu minutes\n", names[(int) p],
  450.              read_timer (thetimer) / MSPMINUTE,
  451.              dur_timer (thetimer) / MSPMINUTE);
  452.         return 0;
  453.     }
  454.     stop_timer (thetimer);    /* just in case */
  455.     thetimer->func = (void (*)(void *)) thefunc;    /* what to call on timeout */
  456.     thetimer->arg = NULL;    /* dummy value */
  457.     set_timer (thetimer, atol (argv[1]) * MSPMINUTE);    /* set timer duration */
  458.     /*    (*thefunc)(NULL);    *//*  Do one now and start it all!*/
  459.     start_detached_timer (thetimer);    /* fire it up */
  460.     return 0;
  461. }
  462.  
  463.  
  464.  
  465. static int
  466. doexpkick (int argc OPTIONAL, char *argv[]OPTIONAL, void *p OPTIONAL)
  467. {
  468. void (*thefunc) (void *);    /* Function to call at expiration */
  469.  
  470. #ifdef WPAGES
  471.     thefunc = (p) ? Oldbidtick : Oldwpagestick;
  472. #else
  473.     thefunc = Oldbidtick;
  474. #endif
  475.     (*thefunc) (NULL);
  476.     return 0;
  477. }
  478.  
  479.  
  480.  
  481. static int
  482. dobidkick (int argc, char *argv[], void *p)
  483. {
  484. #ifdef POOLED
  485. int hasexpired = 0;
  486. time_t now;
  487. time_t age;
  488. struct membid *mb;
  489.  
  490.     if (!MemBid)
  491. #endif
  492.         return (doexpkick (argc, argv, p));
  493. #ifdef POOLED
  494.     stop_timer (&Oldbidtimer);
  495.     log (-1, "Oldbid: processing");
  496.     age = (time_t) (Oldbid_age * 86400L);
  497.     kwait (NULL);
  498.  
  499.     unlink (Historyfile);
  500.     now = time (&now);
  501.  
  502.     for (mb = MemBidTop; mb; mb = mb->next) {
  503.         kwait (NULL);
  504.         if (mb->bid[0] == '$')
  505.             continue;    /* skip deleted bid */
  506.         if (now - mb->time < age)
  507.             bid_add (mb->bid, mb->time, 2, mb->to);
  508.         else
  509.             hasexpired++;
  510.     }
  511.  
  512.     if (hasexpired)
  513.         log (-1, "Oldbid: %d expired", hasexpired);
  514.     bid_load (0);
  515.     start_detached_timer (&Oldbidtimer);
  516.     return 0;
  517. #endif
  518. }
  519.  
  520.  
  521.  
  522. static int
  523. doage (int argc, char *argv[], void *p)
  524. {
  525. int *theage;
  526.  
  527. #ifdef WPAGES
  528.     theage = (p) ? &Oldbid_age : &Oldwpages_age;
  529. #else
  530.     theage = &Oldbid_age;
  531. #endif
  532.     if (argc < 2)
  533.         tprintf ("%s age: %d days\n", names[(int) p], *theage);
  534.     else
  535.         *theage = atoi (argv[1]);
  536.     return 0;
  537. }
  538.  
  539.  
  540.  
  541. #ifdef POOLED
  542. static void
  543. bid_load (int mode)
  544. {
  545. FILE *fp;
  546. char *cp, *cp2, buf[LINELEN + 1];
  547. long count = 0;
  548.  
  549.     if (MemBid) {
  550.         pool_free (&membid_pool);
  551.         MemBidTop = NULLMEMBID;
  552.         if ((fp = fopen (Historyfile, READ_TEXT)) == NULLFILE)
  553.             return;
  554.  
  555.         while (!feof (fp)) {
  556.             kwait (NULL);
  557.             (void) fgets (buf, LINELEN, fp);
  558.             if (feof (fp))
  559.                 continue;
  560.             rip (buf);
  561.             cp = strchr (buf, ' ');
  562.             if (!cp)
  563.                 continue;
  564.             *cp++ = 0;
  565.             cp2 = skipwhite (cp);
  566.             cp2 = skipnonwhite (cp2);
  567.             cp2 = skipwhite (cp2);
  568.             bid_add (buf, atol (cp), 0, cp2);
  569.             count++;
  570.         }
  571.         (void) fclose (fp);
  572.     }
  573.     if (mode)
  574.         tprintf ("There were %ld bids read\n", count);
  575. }
  576.  
  577. #endif
  578.  
  579.  
  580.  
  581. void
  582. bid_add (char *bid, time_t now, int tofile, char *to)
  583. {
  584. FILE *fp;
  585. #ifdef POOLED
  586. struct membid *mb;
  587. #endif
  588.  
  589.     /* tofile == 0 - add in memory only - don't check for bid_load
  590.      * tofile == 1 - add to memory and file
  591.      * tofile == 2 - add to file only
  592.      */
  593.  
  594. #ifdef POOLED
  595.     if (tofile != 2 && MemBid) {
  596.         if (tofile && !membid_pool.top)
  597.             bid_load (0);
  598.         mb = (struct membid *) pool_alloc (&membid_pool);
  599.         mb->next = MemBidTop;
  600.         MemBidTop = mb;
  601.         strncpy (mb->bid, bid, 13);
  602.         strncpy (mb->to, to, 13);
  603.         mb->time = (long) now;
  604.     }
  605. #endif
  606.     if (tofile && (fp = fopen (Historyfile, APPEND_TEXT)) != NULL) {
  607.         fprintf (fp, "%-13.13s %-14ld %s\n", bid, now, to);    /* Save BID */
  608.         (void) fclose (fp);
  609.     }
  610. }
  611.  
  612.  
  613.  
  614. int
  615. bid_check (register char *string)
  616. {
  617. int retval = 0;
  618. char buf[LINELEN];
  619. register FILE *fp;
  620.  
  621. #ifdef POOLED
  622. struct membid *mb;
  623.  
  624.     if (MemBid) {
  625.         if (!membid_pool.top)
  626.             bid_load (0);
  627.         for (mb = MemBidTop; mb; mb = mb->next) {
  628.             if (mb->bid[0] == '$')
  629.                 continue;
  630.             if (!strnicmp (string, mb->bid, strlen (string))) {
  631.                 retval = 1;
  632.                 break;
  633.             }
  634.         }
  635.     } else {
  636. #endif
  637.         if ((fp = fopen (Historyfile, READ_TEXT)) == NULLFILE)
  638.             return 0;
  639.  
  640.         while (!feof (fp)) {
  641.             kwait (NULL);
  642.             (void) fgets (buf, LINELEN, fp);
  643.             if (feof (fp))
  644.                 continue;
  645.             if (*buf == '$')
  646.                 continue;
  647.             if (!strnicmp (string, buf, strlen (string))) {
  648.                 retval = 1;
  649.                 break;
  650.             }
  651.         }
  652.         (void) fclose (fp);
  653. #ifdef POOLED
  654.     }
  655. #endif
  656.     return (retval);
  657. }
  658.  
  659.  
  660.  
  661. /* Releases a bid from the history file. Used when a personal message
  662.  * is forwarded off the system. Lets it be able to come back here,
  663.  * if needed.
  664.  */
  665. void
  666. bid_delete (register char *string)
  667. {
  668. register FILE *fp;
  669. char buf[LINELEN];
  670. long theindex;
  671. #ifdef POOLED
  672. struct membid *mb;
  673. #endif
  674.  
  675.     if (string == NULLCHAR)
  676.         return;
  677.  
  678. #ifdef POOLED
  679.     if (MemBid) {
  680.         if (!membid_pool.top)
  681.             bid_load (0);
  682.         for (mb = MemBidTop; mb; mb = mb->next) {
  683.             if (mb->bid[0] == '$')
  684.                 continue;
  685.             if (!strnicmp (string, mb->bid, strlen (string))) {
  686.                 mb->bid[0] = '$';
  687.                 break;
  688.             }
  689.         }
  690.     } else {
  691. #endif
  692.         if ((fp = fopen (Historyfile, UPDATE_TEXT)) == NULLFILE)
  693.             return;
  694.  
  695.         while (!feof (fp)) {
  696.             kwait (NULL);
  697.             theindex = ftell (fp);
  698.             (void) fgets (buf, LINELEN, fp);
  699.             if (feof (fp))
  700.                 continue;
  701.             if (*buf == '$')
  702.                 continue;
  703.             if (!strnicmp (string, buf, 13)) {
  704.                 fseek (fp, theindex, SEEK_SET);
  705.                 fputc ('$', fp);
  706.                 break;
  707.             }
  708.         }
  709.         (void) fclose (fp);
  710. #ifdef POOLED
  711.     }
  712. #endif
  713.     kwait (NULL);
  714. }
  715.  
  716.  
  717.  
  718. #ifdef WPAGES
  719.  
  720. static int
  721. dowpsupport (int argc, char *argv[], void *p OPTIONAL)
  722. {
  723.     return setbool (&MbWpages, "Use White Pages dbase", argc, argv);
  724. }
  725.  
  726.  
  727.  
  728. static int
  729. dowpserver (int argc, char *argv[], void *p OPTIONAL)
  730. {
  731.     return setbool (&WPServer, "Enable WP Server - process incoming WP messages", argc, argv);
  732. }
  733.  
  734.  
  735.  
  736. static int
  737. dowpclient (int argc, char *argv[], void *p OPTIONAL)
  738. {
  739.     return setbool (&WPClient, "Enable WP Client - process WP updates", argc, argv);
  740. }
  741.  
  742.  
  743.  
  744. static int
  745. dowpclicall (int argc, char *argv[], void *p OPTIONAL)
  746. {
  747. char buf[128], *cp;
  748.  
  749.     strncpy (buf,
  750. #ifdef MBFWD    /* just in case ;-) */
  751.         (BIDsuffix) ? BIDsuffix :
  752. #endif
  753.         Hostname, 128);
  754.     if ((cp = strchr (buf, '.')) != NULLCHAR)
  755.         *cp = 0;
  756.  
  757.     if (argc > 1)    {
  758.         free (WPcall);
  759.         WPcall = strdup (argv[1]);
  760.     }
  761.         
  762.     tputs ("WP updates will be sent from ");
  763.     if (!WPcall)
  764.         tprintf ("WP@%s - no clientcall set\n", buf);
  765.     else
  766.         tprintf ("%s@%s\n", WPcall, buf);
  767.  
  768.     return 0;
  769. }
  770.  
  771.  
  772.  
  773. static int
  774. dowpdest (int argc, char *argv[], void *p OPTIONAL)
  775. {
  776. int k;
  777.  
  778.     if (argc == 1) {
  779.         if (!WPdestinations[0])
  780.             tputs ("No WP update destinations are defined\n");
  781.         else {
  782.             tputs ("WP updates will be sent to the following PBBSs...\n\n");
  783.             for (k = 0; k < WPDEST; k++)
  784.                 if (WPdestinations[k])
  785.                     tprintf ("%s\n", WPdestinations[k]);
  786.         }
  787.         return 0;
  788.     }
  789.     for (k = 0; k < WPDEST; k++)
  790.         if (!WPdestinations[k]) {
  791.             WPdestinations[k] = strdup (argv[1]);
  792.             break;
  793.         }
  794.     if (k == WPDEST)
  795.         tprintf ("Sorry, but the maximum of %d update destinations were already defined!\007\n", WPDEST);
  796.     return 0;
  797. }
  798.  
  799.  
  800.  
  801. static int
  802. dowpupdate (int argc, char *argv[], void *p OPTIONAL)
  803. {
  804.     if (argc < 2) {
  805.         tprintf ("timer: %lu/%lu hrs\n",
  806.              read_timer (&WPUpdatetimer) / MSPHOUR,
  807.              dur_timer (&WPUpdatetimer) / MSPHOUR);
  808.         return 0;
  809.     }
  810.     if (*argv[1] == 'n') {
  811.         WPUpdatetick (NULL);
  812.         return 0;
  813.     }
  814.     /* set the timer */
  815.     stop_timer (&WPUpdatetimer);    /* Just in case */
  816.     WPUpdatetimer.func = (void (*)(void *)) WPUpdatetick;    /* what to call on timeout */
  817.     WPUpdatetimer.arg = NULL;    /* dummy value */
  818.     set_timer (&WPUpdatetimer, atol (argv[1]) * MSPHOUR);    /* set timer duration */
  819.     start_detached_timer (&WPUpdatetimer);
  820.     return 0;
  821. }
  822.  
  823.  
  824.  
  825. static void
  826. WPUpdatetick (void *p OPTIONAL)
  827. {
  828. int k;
  829. FILE *fp;
  830. char here[128];
  831. char there[128];
  832.  
  833.     start_detached_timer (&WPUpdatetimer);
  834.  
  835.     if (WPClient) {
  836.         fp = fopen (WPUpdateFile, READ_TEXT);
  837.         if (!fp)
  838.             return;
  839.         sprintf (here, "%s@%s", (WPcall) ? WPcall : "WP", Hostname);
  840.         for (k = 0; k < WPDEST; k++) {
  841.             if (WPdestinations[k]) {
  842.                 log (-1, "WP Update sent to: %s", WPdestinations[k]);
  843.                 rewind (fp);
  844.                 sprintf (there, "WP@%s", WPdestinations[k]);
  845.                 (void) rdaemon (fp, NULLCHAR, here, there, "WP Update", 'P', 0);
  846.             }
  847.         }
  848.         (void) fclose (fp);
  849.     }
  850.     unlink (WPUpdateFile);
  851. }
  852.  
  853.  
  854.  
  855. void
  856. add_WPUpdate (char *origcall, char *home, char *name, char which)
  857. {
  858. FILE *fp;
  859. time_t now;
  860. struct tm *t;
  861. char *bbshier, *who = NULLCHAR, *cp;
  862. char here[80];
  863. char *call;
  864.  
  865.     if (!WPClient)
  866.         return;
  867.     if (which == 'X' || which == 'T')
  868.         return;
  869.     fp = fopen (WPUpdateFile, APPEND_TEXT);
  870.     if (!fp)
  871.         return;
  872.     (void) time (&now);
  873.     t = localtime (&now);
  874.  
  875.     call = strdup (origcall);
  876.     (void) strupr (call);
  877.     cp = strpbrk (call, ".#@[");
  878.     if (cp)
  879.         *cp = 0;
  880.     if (mbxRCall)
  881.         strncpy (here, mbxRCall, 80);
  882.     else
  883.         (void) pax25 (here, Mycall);
  884.     if (!home || !stricmp (here, home)) {
  885.         if (Mbhaddress) {
  886.             strcat (here, ".");
  887.             strcat (here, Mbhaddress);
  888.         }
  889.         bbshier = strdup (here);
  890.     } else
  891.         bbshier = wpageCheck (home, 1, 0, 'X');
  892.     if (bbshier) {
  893.         if (name) {
  894.             who = strdup (&name[1]);
  895.             cp = strpbrk (who, " )");
  896.             if (cp)
  897.                 *cp = 0;
  898.         }
  899.         fprintf (fp, "On %02d%02d%02d %s/%c @ %s zip ? %s ?\n",
  900.              t->tm_year, t->tm_mon + 1, t->tm_mday, call, which,
  901.              bbshier, (who && *who) ? who : "?");
  902.         if (who)
  903.             free (who);
  904.         free (bbshier);
  905.     }
  906.     free (call);
  907.     (void) fclose (fp);
  908. }
  909.  
  910.  
  911.  
  912. int
  913. wpserver (FILE *fp, const char *from OPTIONAL)
  914. {
  915. char buf[512], subject[256], realfrom[128], *cp;
  916. long startat;
  917. char call[12], bbs[80], zip[12], name[64], *qth, updatetype = 'I';
  918. int k;
  919.  
  920.     if (!WPServer)
  921.         return 0;
  922.     parseheader (fp, realfrom, subject, NULLCHAR, NULLCHAR, buf, &startat);
  923.     cp = strchr (realfrom, '@');
  924.     if (cp)
  925.         *cp++ = 0;
  926.     log (-1, "WP Updates received from %s", (cp) ? cp : "unknown source");
  927.     fseek (fp, startat, SEEK_SET);
  928.     if (realfrom[0] && subject[0]) {
  929.         while (fgets (buf, 512, fp) != NULLCHAR) {
  930.             if (!strnicmp ("On ", buf, 3)) {    /* this is a WP Update line */
  931.                 rip (buf);
  932.                 sscanf (&buf[10], "%s @ %s zip %s %s",
  933.                     call, bbs, zip, name);
  934.                 qth = buf;
  935.                 for (k = 0; k < 8; k++) {
  936.                     qth = strchr (qth, ' ');
  937.                     if (qth)
  938.                         qth++;
  939.                     else
  940.                         break;
  941.                 }
  942.                 if (!qth)
  943.                     continue;
  944.                 cp = strchr (call, '/');
  945.                 if (cp) {
  946.                     *cp++ = 0;
  947.                     updatetype = *cp;
  948.                 }
  949. #if 0
  950.                 tcmdprintf ("Received WP Update [%c]: %s @ %s (%s) zip=%s qth=%s\n",
  951.                      updatetype, call, bbs, name, zip, qth);
  952. #endif
  953.                 if (updatetype != 'I') {
  954.                     sprintf (name, "%s@%s", call, bbs);
  955.                     wpageAdd (name, 0, (updatetype == 'G') ? 0 : 1, 'X');
  956.                 } else
  957.                     wpageAdd (bbs, 1, 1, 'X');
  958.             }
  959.         }
  960.     }
  961.     return 1;
  962. }
  963. #endif
  964.  
  965.  
  966.  
  967. #ifdef MBFWD
  968. int
  969. dombbid (int argc OPTIONAL, char *argv[], void *p OPTIONAL)
  970. {
  971. char buf[LINELEN], *cp = NULLCHAR;
  972. register FILE *fp;
  973.  
  974. #ifdef POOLED
  975. struct membid *mb;
  976.  
  977.     if (MemBid) {
  978.         if (!membid_pool.top)
  979.             bid_load (0);
  980.         for (mb = MemBidTop; mb; mb = mb->next) {
  981.             if (strnicmp (mb->bid, argv[1], strlen (argv[1])))
  982.                 continue;
  983.             cp = mb->to;
  984.             break;
  985.         }
  986.     } else {
  987. #endif
  988.         if ((fp = fopen (Historyfile, READ_TEXT)) == NULLFILE)
  989.             return 0;
  990.  
  991.         while (!feof (fp)) {
  992.             kwait (NULL);
  993.             (void) fgets (buf, LINELEN, fp);
  994.             if (feof (fp))
  995.                 continue;
  996.             if (strnicmp (argv[1], buf, strlen (argv[1])))
  997.                 continue;
  998.             rip (buf);
  999.             cp = skipnonwhite (buf);
  1000.             cp = skipwhite (cp);
  1001.             cp = skipnonwhite (cp);
  1002.             cp = skipwhite (cp);
  1003.             break;
  1004.         }
  1005.         (void) fclose (fp);
  1006. #ifdef POOLED
  1007.     }
  1008. #endif
  1009.     if (cp == NULLCHAR || !*cp)
  1010.         tprintf ("\nBid '%s' is either NOT on the system, or cannot be located\n", argv[1]);
  1011.     else
  1012.         tprintf ("\nBid '%s' is in area '%s'\n", argv[1], cp);
  1013.     return 0;
  1014.  
  1015. }
  1016. #endif
  1017.